package com.cch.demo.sys.Aspect;

import cn.hutool.core.bean.BeanUtil;
import com.cch.demo.sys.domain.Dept;
import com.cch.demo.sys.domain.User;
import com.cch.demo.sys.vo.DeptVo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class CacheAspect {

    private Log log = LogFactory.getLog(CacheAspect.class);

    //声明一个缓存容器
    //从CachePool中获取缓存容器
    private Map<String,Object> CACHE_CONTAINER=CachePool.CACHE_CONTAINER;

    private static final String POINTCUT_DEPT_GET = "execution(* com.cch.demo.sys.service.impl.DeptServiceImpl.getById(..))";
    private static final String POINTCUT_DEPT_INSERT = "execution(* com.cch.demo.sys.service.impl.DeptServiceImpl.save(..))";
    private static final String POINTCUT_DEPT_UPDETE = "execution(* com.cch.demo.sys.service.impl.DeptServiceImpl.updateById(..))";
    private static final String POINTCUT_DEPT_DELETE = "execution(* com.cch.demo.sys.service.impl.DeptServiceImpl.removeById(..))";

    private static final String CACHE_DEPT_PROFIX="dept:";

    /**
     * 插入缓存
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_DEPT_INSERT)
    public Boolean cacheDeptInsert(ProceedingJoinPoint joinPoint) throws Throwable {
        Dept dept = (Dept)joinPoint.getArgs()[0];
        Boolean isSuccess = (Boolean)joinPoint.proceed();
        if(isSuccess){
            log.info("---向缓存中插入"+CACHE_DEPT_PROFIX+dept.getId());
            CACHE_CONTAINER.put(CACHE_DEPT_PROFIX+dept.getId(),dept);
            return isSuccess;
        }else{
            return isSuccess;
        }
    }
     /**
     * 查询缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_DEPT_GET)
    public Dept cacheDeptGet(ProceedingJoinPoint jionPoint) throws Throwable {

        Integer id = (Integer)jionPoint.getArgs()[0];
        Dept dept = (Dept)CACHE_CONTAINER.get(CACHE_DEPT_PROFIX+id);
        if(dept!=null){
            log.info("---缓存中存在"+CACHE_DEPT_PROFIX+id);
            return dept;
        }else{
            log.info("---缓存中不存在"+CACHE_DEPT_PROFIX+id);
            dept = (Dept)jionPoint.proceed();
            CACHE_CONTAINER.put(CACHE_DEPT_PROFIX+id,dept);
            return dept;
        }
    }

    /**
     * 修改缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_DEPT_UPDETE)
    public Boolean cacheDeptUpdate(ProceedingJoinPoint jionPoint) throws Throwable {
        Dept dept1 = (DeptVo)jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if (isSuccess){
            //从缓存中获取Dept
           Dept dept = (Dept) CACHE_CONTAINER.get(CACHE_DEPT_PROFIX+dept1.getId());
           //如果缓存中存在该dept
           if(dept!=null){
               log.info("----缓存中存在未修改的"+CACHE_DEPT_PROFIX+dept1.getId()+"进行删除重新加载");
               //移除原先的dept
               CACHE_CONTAINER.remove(CACHE_DEPT_PROFIX+dept1.getId());
               //插入修改后的dept
               Dept dept2 = new Dept();
               BeanUtil.copyProperties(dept1,dept2);
               CACHE_CONTAINER.put(CACHE_DEPT_PROFIX+dept1.getId(),dept2);
           //缓存中不存在该Dept
           }else{
               log.info("-----缓存中不存在未修改的"+CACHE_DEPT_PROFIX+dept1.getId());
              Dept dept2 = new Dept();
               BeanUtil.copyProperties(dept1,dept2);
               CACHE_CONTAINER.put(CACHE_DEPT_PROFIX+dept1.getId(),dept2);
           }
        }
        return isSuccess;
    }

    @Around(value = POINTCUT_DEPT_DELETE)
    public Boolean cacheDeptDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Integer id = (Integer) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            Dept dept = (Dept)CACHE_CONTAINER.get(CACHE_DEPT_PROFIX+id);
            if(dept!=null){
                log.info("删除缓存中的Dept");
                CACHE_CONTAINER.remove(CACHE_DEPT_PROFIX+id);
            }
        }
        return isSuccess;
    }

    private static final String POINTCUT_USER_GET = "execution(* com.cch.demo.sys.service.impl.UserServiceImpl.getById(..))";
    private static final String POINTCUT_USER_INSERT = "execution(* com.cch.demo.sys.service.impl.UserServiceImpl.save(..))";
    private static final String POINTCUT_USER_UPDETE = "execution(* com.cch.demo.sys.service.impl.UserServiceImpl.updateById(..))";
    private static final String POINTCUT_USER_DELETE = "execution(* com.cch.demo.sys.service.impl.UserServiceImpl.removeById(..))";

    private static final String CACHE_USER_PROFIX="user:";


    @Around(value = POINTCUT_USER_INSERT)
    public Boolean cacheUserInsert(ProceedingJoinPoint joinPoint) throws Throwable {
        User user = (User)joinPoint.getArgs()[0];
        Boolean isSuccess = (Boolean)joinPoint.proceed();
        if(isSuccess){
            log.info(isSuccess+"---向缓存中插入"+CACHE_DEPT_PROFIX+user.getId());
            CACHE_CONTAINER.put(CACHE_USER_PROFIX+user.getId(),user);
            return isSuccess;
        }else{
            return isSuccess;
        }
    }
    /**
     * 查询缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_USER_GET)
    public User cacheUserGet(ProceedingJoinPoint jionPoint) throws Throwable {

        Integer id = (Integer)jionPoint.getArgs()[0];
        User user = (User)CACHE_CONTAINER.get(CACHE_USER_PROFIX+id);
        if(user!=null){
            log.info("---缓存中存在"+CACHE_USER_PROFIX+id);
            return user;
        }else{
            log.info("---缓存不中存在"+CACHE_USER_PROFIX+id);
            user = (User)jionPoint.proceed();
            CACHE_CONTAINER.put(CACHE_USER_PROFIX+id,user);
            return user;
        }
    }

    /**
     * 修改缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_USER_UPDETE)
    public Boolean cacheUserUpdate(ProceedingJoinPoint jionPoint) throws Throwable {
        User user1 = (User)jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if (isSuccess){
            //从缓存中获取User
            User user = (User) CACHE_CONTAINER.get(CACHE_USER_PROFIX+user1.getId());
            //如果缓存中存在该user
            if(user!=null){
                log.info("----缓存中存在未修改的"+CACHE_USER_PROFIX+user1.getId());
                //移除原先的user
                CACHE_CONTAINER.remove(CACHE_USER_PROFIX+user1.getId());
                //插入修改后的user
                User user2 = new User();
                BeanUtil.copyProperties(user1,user2);
                CACHE_CONTAINER.put(CACHE_USER_PROFIX+user1.getId(),user2);
                //缓存中不存在该User
            }else{
                log.info("----缓存中不存在未修改的"+CACHE_USER_PROFIX+user1.getId());
                User user2 = new User();
                BeanUtil.copyProperties(user1,user2);
                CACHE_CONTAINER.put(CACHE_USER_PROFIX+user1.getId(),user2);
            }
        }
        return isSuccess;
    }

    @Around(value = POINTCUT_USER_DELETE)
    public Boolean cacheUserDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Integer id = (Integer) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            User user = (User)CACHE_CONTAINER.get(CACHE_USER_PROFIX+id);
            if(user!=null){
                log.info("删除缓存中的User");
                CACHE_CONTAINER.remove(CACHE_USER_PROFIX+id);
            }
        }
        return isSuccess;
    }
}
